import time
from quant.const import OrderStatus
from quant.utils import logging


class UserData:
    def __init__(self, event, api_type, data):
        self.event = event
        self.api_type = api_type
        self.data = data

    def __repr__(self):
        return 'UserData({}, {}):\n      {}'.format(self.event, self.api_type, self.data)


class Order:
    def __init__(self, symbol=None, side=None, price=None, amount=None, client_id=None, order_id=None, order_type=None, offset=None, status=None):
        self.symbol = symbol
        self.side = side
        self.price = price
        self.amount = amount

        self.client_id = client_id
        self.order_id = order_id

        self.order_type = order_type
        self.status = status
        self.offset = offset

        self.operate_time = None
        self.orig_amount = None
        # if add new var, edit _get_attr_dic()!

    def __repr__(self):
        result = 'Order({})'
        params = ', '.join([f'{key}={value}' for key, value in self._get_attr_dic().items()])
        return result.format(params)

    def copy(self):
        order = Order()
        for key, value in self._get_attr_dic().items():
            order.__setattr__(key, value)
        return order

    def operate_now(self):
        self.operate_time = time.time()

    def update(self, order):
        self_attr = self._get_attr_dic()
        other_attr = order._get_attr_dic()

        if (self.status, order.status) in status_update_exception:
            other_attr['status'] = status_update_exception[(self.status, order.status)]
            if order.status != OrderStatus.PartFilled:
                logging.info('order update from {} to {}, refused.'.format(self.status, order.status))

        difference = {}
        for key, value in other_attr.items():
            if value is not None:
                self_value = self_attr[key]
                if value != self_value:
                    difference[key] = (self_value, value)
                    setattr(self, key, value)

        return difference

    def _get_attr_dic(self):
        result = dict(
            symbol=self.symbol,
            side=self.side,
            price=self.price,
            amount=self.amount,
            client_id=self.client_id,
            order_id=self.order_id,
            order_type=self.order_type,
            status=self.status,
            offset=self.offset,
            operate_time=self.operate_time,
            orig_amount=self.orig_amount
        )
        return result


_st = OrderStatus
status_update_exception = {
    # (_st.Canceling, _st.Pending): _st.Canceling,
    (_st.Canceling, _st.PartFilled): _st.Canceling,
}


if __name__ == '__main__':
    from quant.utils import set_test_mode
    set_test_mode()

    o1 = Order(status=OrderStatus.Canceling)
    o2 = Order(status=OrderStatus.Pending)
    o2.orig_amount = 1

    o1.update(o2)
    print(o1)





















